package com.yili.printer.service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

import com.zebra.sdk.comm.ConnectionException;
import com.yili.printer.generator.Generator;

/**
 * 打印服务类
 * 负责处理打印业务逻辑
 */
@Service
public class PrintService {

    private static final Logger logger = LogManager.getLogger(PrintService.class);

    /**
     * 斑马打印机实例
     */
    private ZebraPrinter zebraPrinter;

    /**
     * 构造函数
     * 通过依赖注入初始化ZebraPrinter
     */
    @Autowired
    public PrintService(ZebraPrinter zebraPrinter) {
        this.zebraPrinter = zebraPrinter;
    }

    /**
     * 应用启动时初始化打印机连接
     */
    @PostConstruct
    public void initializePrinter() {
        logger.info("应用启动，开始初始化打印机连接");
        try {
            zebraPrinter.connect();
            logger.info("打印机连接初始化成功");
        } catch (Exception e) {
            logger.error("打印机连接初始化异常，将在使用时重试", e);
        }
    }

    /**
     * 应用关闭时清理打印机资源
     */
    @PreDestroy
    public void cleanupPrinter() {
        logger.info("应用关闭，开始清理打印机资源");
        try {
            zebraPrinter.disconnect();
            logger.info("打印机资源清理完成");
        } catch (Exception e) {
            logger.error("清理打印机资源时发生异常", e);
        }
    }

    /**
     * 初始化打印服务
     * 
     * @throws ConnectionException 连接异常
     */
    public void initialize() throws ConnectionException {
        logger.info("开始初始化打印服务");
        try {
            zebraPrinter.connect();
            logger.info("打印服务初始化完成，结果: 成功");
        } catch (ConnectionException e) {
            logger.error("打印服务初始化失败", e);
            throw e;
        } catch (Exception e) {
            logger.error("打印服务初始化失败", e);
            throw new ConnectionException("初始化打印服务时发生未知错误: " + e.getMessage(), e);
        }
    }

    /**
     * 获取打印机连接状态
     * 
     * @return 连接状态
     * @throws ConnectionException
     */
    public boolean getPrinterStatus() throws ConnectionException {
        logger.debug("获取打印机连接状态");
        boolean status = zebraPrinter.isConnected();
        logger.info("打印机状态查询完成，状态: " + (status ? "已连接" : "未连接"));
        return status;
    }

    /**
     * 执行打印标签操作
     * 使用指定的Generator生成打印数据
     * 
     * @param printData 打印内容Map，包含标签所需的各种数据
     * @param generator 标签生成器
     * @throws ConnectionException      连接异常
     * @throws IllegalArgumentException 参数异常
     */
    public synchronized void printLabel(Map<String, String> printData, Generator generator) throws ConnectionException {
        if (printData == null || printData.isEmpty()) {
            logger.warn("打印内容为空，无法执行打印操作");
            throw new IllegalArgumentException("打印内容不能为空");
        }

        logger.info("开始执行打印标签操作");
        logger.debug("打印内容: " + printData.toString());

        try {
            // 确保打印机连接可用
            ensurePrinterConnection();

            // 使用指定的标签生成器生成打印数据
            String zplData = generator.generate(printData);
            zebraPrinter.sendPrintData(zplData);
            logger.info("标签打印完成");
        } catch (ConnectionException e) {
            logger.error("标签打印失败", e);
            throw e;
        } catch (Exception e) {
            logger.error("标签打印失败", e);
            throw new ConnectionException("打印标签时发生未知错误: " + e.getMessage(), e);
        }
    }

    /**
     * 关闭打印服务
     * 
     * @throws ConnectionException 连接异常
     */
    public void shutdown() throws ConnectionException {
        logger.info("开始关闭打印服务");
        try {
            zebraPrinter.disconnect();
            logger.info("打印服务关闭完成，结果: 成功");
        } catch (ConnectionException e) {
            logger.error("关闭打印服务失败", e);
            throw e;
        } catch (Exception e) {
            logger.error("关闭打印服务失败", e);
            throw new ConnectionException("关闭打印服务时发生未知错误: " + e.getMessage(), e);
        }
    }

    /**
     * 检查并确保打印机连接可用
     * 
     * @throws ConnectionException 连接异常
     */
    private synchronized void ensurePrinterConnection() throws ConnectionException {
        try {
            // 检查当前连接状态
            if (zebraPrinter.isConnected()) {
                return;
            }

            logger.info("打印机连接已断开，尝试重新连接");
            zebraPrinter.connect();
        } catch (ConnectionException e) {
            logger.warn("检查打印机连接状态失败，尝试重新连接", e);
            try {
                zebraPrinter.connect();
            } catch (ConnectionException reconnectException) {
                logger.error("重新连接打印机失败", reconnectException);
                throw reconnectException;
            } catch (Exception reconnectException) {
                logger.error("重新连接打印机失败", reconnectException);
                throw new ConnectionException("重新连接打印机时发生未知错误: " + reconnectException.getMessage(), reconnectException);
            }
        } catch (Exception e) {
            logger.warn("检查打印机连接状态失败，尝试重新连接", e);
            try {
                zebraPrinter.connect();
            } catch (Exception reconnectException) {
                logger.error("重新连接打印机失败", reconnectException);
                throw new ConnectionException("重新连接打印机时发生未知错误: " + reconnectException.getMessage(), reconnectException);
            }
        }
    }
}